<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Eroding and Dilating</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d9/df8/tutorial_root.html">OpenCV Tutorials</a></li><li class="navelem"><a class="el" href="../../d7/da8/tutorial_table_of_content_imgproc.html">Image Processing (imgproc module)</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Eroding and Dilating </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><b>Prev Tutorial:</b> <a class="el" href="../../dc/dd3/tutorial_gausian_median_blur_bilateral_filter.html">Smoothing Images</a></p>
<p><b>Next Tutorial:</b> <a class="el" href="../../d3/dbe/tutorial_opening_closing_hats.html">More Morphology Transformations</a></p>
<table class="doxtable">
<tr>
<th align="right"></th><th align="left"></th></tr>
<tr>
<td align="right">Original author </td><td align="left">Ana Huamán </td></tr>
<tr>
<td align="right">Compatibility </td><td align="left">OpenCV &gt;= 3.0 </td></tr>
</table>
<h2>Goal </h2>
<p>In this tutorial you will learn how to:</p>
<ul>
<li>Apply two very common morphological operators: Erosion and Dilation. For this purpose, you will use the following OpenCV functions:<ul>
<li><a class="el" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">cv::erode</a></li>
<li><a class="el" href="../../d4/d86/group__imgproc__filter.html#ga4ff0f3318642c4f469d0e11f242f3b6c">cv::dilate</a></li>
</ul>
</li>
</ul>
<dl class="section note"><dt>Note</dt><dd>The explanation below belongs to the book <b>Learning OpenCV</b> by Bradski and Kaehler.</dd></dl>
<h2>Morphological Operations </h2>
<ul>
<li>In short: A set of operations that process images based on shapes. Morphological operations apply a <em>structuring element</em> to an input image and generate an output image.</li>
<li>The most basic morphological operations are: Erosion and Dilation. They have a wide array of uses, i.e. :<ul>
<li>Removing noise</li>
<li>Isolation of individual elements and joining disparate elements in an image.</li>
<li>Finding of intensity bumps or holes in an image</li>
</ul>
</li>
<li><p class="startli">We will explain dilation and erosion briefly, using the following image as an example:</p>
<div class="image">
<img src="../../Morphology_1_Tutorial_Theory_Original_Image.png" alt="Morphology_1_Tutorial_Theory_Original_Image.png"/>
</div>
</li>
</ul>
<h3>Dilation</h3>
<ul>
<li>This operations consists of convolving an image \(A\) with some kernel ( \(B\)), which can have any shape or size, usually a square or circle.</li>
<li>The kernel \(B\) has a defined <em>anchor point</em>, usually being the center of the kernel.</li>
<li>As the kernel \(B\) is scanned over the image, we compute the maximal pixel value overlapped by \(B\) and replace the image pixel in the anchor point position with that maximal value. As you can deduce, this maximizing operation causes bright regions within an image to "grow" (therefore the name <em>dilation</em>).</li>
<li>The dilatation operation is: \(\texttt{dst} (x,y) = \max _{(x&#39;,y&#39;): \, \texttt{element} (x&#39;,y&#39;) \ne0 } \texttt{src} (x+x&#39;,y+y&#39;)\)</li>
<li><p class="startli">Take the above image as an example. Applying dilation we can get:</p>
<div class="image">
<img src="../../Morphology_1_Tutorial_Theory_Dilation.png" alt="Morphology_1_Tutorial_Theory_Dilation.png"/>
</div>
</li>
<li>The bright area of the letter dilates around the black regions of the background.</li>
</ul>
<h3>Erosion</h3>
<ul>
<li>This operation is the sister of dilation. It computes a local minimum over the area of given kernel.</li>
<li>As the kernel \(B\) is scanned over the image, we compute the minimal pixel value overlapped by \(B\) and replace the image pixel under the anchor point with that minimal value.</li>
<li>The erosion operation is: \(\texttt{dst} (x,y) = \min _{(x&#39;,y&#39;): \, \texttt{element} (x&#39;,y&#39;) \ne0 } \texttt{src} (x+x&#39;,y+y&#39;)\)</li>
<li><p class="startli">Analagously to the example for dilation, we can apply the erosion operator to the original image (shown above). You can see in the result below that the bright areas of the image get thinner, whereas the dark zones gets bigger.</p>
<div class="image">
<img src="../../Morphology_1_Tutorial_Theory_Erosion.png" alt="Morphology_1_Tutorial_Theory_Erosion.png"/>
</div>
</li>
</ul>
<h2>Code </h2>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'><p> This tutorial's code is shown below. You can also download it <a href="https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp">here</a> </p><div class="fragment"><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="../../d1/d4f/imgproc_2include_2opencv2_2imgproc_8hpp.html">opencv2/imgproc.hpp</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="../../d4/dd5/highgui_8hpp.html">opencv2/highgui.hpp</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a>;</div><div class="line"><span class="keyword">using namespace </span>std;</div><div class="line"></div><div class="line"><a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> src, erosion_dst, dilation_dst;</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> erosion_elem = 0;</div><div class="line"><span class="keywordtype">int</span> erosion_size = 0;</div><div class="line"><span class="keywordtype">int</span> dilation_elem = 0;</div><div class="line"><span class="keywordtype">int</span> dilation_size = 0;</div><div class="line"><span class="keywordtype">int</span> <span class="keyword">const</span> max_elem = 2;</div><div class="line"><span class="keywordtype">int</span> <span class="keyword">const</span> max_kernel_size = 21;</div><div class="line"></div><div class="line"><span class="keywordtype">void</span> Erosion( <span class="keywordtype">int</span>, <span class="keywordtype">void</span>* );</div><div class="line"><span class="keywordtype">void</span> Dilation( <span class="keywordtype">int</span>, <span class="keywordtype">void</span>* );</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>** argv )</div><div class="line">{</div><div class="line">  <a class="code" href="../../d0/d2e/classcv_1_1CommandLineParser.html">CommandLineParser</a> parser( argc, argv, <span class="stringliteral">&quot;{@input | LinuxLogo.jpg | input image}&quot;</span> );</div><div class="line">  src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;( <span class="stringliteral">&quot;@input&quot;</span> ) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80af660544735200cbe942eea09232eb822">IMREAD_COLOR</a> );</div><div class="line">  <span class="keywordflow">if</span>( src.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#abbec3525a852e77998aba034813fded4">empty</a>() )</div><div class="line">  {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Could not open or find the image!\n&quot;</span> &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Usage: &quot;</span> &lt;&lt; argv[0] &lt;&lt; <span class="stringliteral">&quot; &lt;Input image&gt;&quot;</span> &lt;&lt; endl;</div><div class="line">    <span class="keywordflow">return</span> -1;</div><div class="line">  }</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">namedWindow</a>( <span class="stringliteral">&quot;Erosion Demo&quot;</span>, <a class="code" href="../../d0/d90/group__highgui__window__flags.html#ggabf7d2c5625bc59ac130287f925557ac3acf621ace7a54954cbac01df27e47228f">WINDOW_AUTOSIZE</a> );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">namedWindow</a>( <span class="stringliteral">&quot;Dilation Demo&quot;</span>, <a class="code" href="../../d0/d90/group__highgui__window__flags.html#ggabf7d2c5625bc59ac130287f925557ac3acf621ace7a54954cbac01df27e47228f">WINDOW_AUTOSIZE</a> );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga8d86b207f7211250dbe6e28f76307ffb">moveWindow</a>( <span class="stringliteral">&quot;Dilation Demo&quot;</span>, src.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa3e5a47585c9ef6a0842556739155e3e">cols</a>, 0 );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Element:\n 0: Rect \n 1: Cross \n 2: Ellipse&quot;</span>, <span class="stringliteral">&quot;Erosion Demo&quot;</span>,</div><div class="line">          &amp;erosion_elem, max_elem,</div><div class="line">          Erosion );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Kernel size:\n 2n +1&quot;</span>, <span class="stringliteral">&quot;Erosion Demo&quot;</span>,</div><div class="line">          &amp;erosion_size, max_kernel_size,</div><div class="line">          Erosion );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Element:\n 0: Rect \n 1: Cross \n 2: Ellipse&quot;</span>, <span class="stringliteral">&quot;Dilation Demo&quot;</span>,</div><div class="line">          &amp;dilation_elem, max_elem,</div><div class="line">          Dilation );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Kernel size:\n 2n +1&quot;</span>, <span class="stringliteral">&quot;Dilation Demo&quot;</span>,</div><div class="line">          &amp;dilation_size, max_kernel_size,</div><div class="line">          Dilation );</div><div class="line"></div><div class="line">  Erosion( 0, 0 );</div><div class="line">  Dilation( 0, 0 );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">waitKey</a>(0);</div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">void</span> Erosion( <span class="keywordtype">int</span>, <span class="keywordtype">void</span>* )</div><div class="line">{</div><div class="line">  <span class="keywordtype">int</span> erosion_type = 0;</div><div class="line">  <span class="keywordflow">if</span>( erosion_elem == 0 ){ erosion_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada260c4cbde19a749726763c01a074c60f">MORPH_RECT</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( erosion_elem == 1 ){ erosion_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada318435753d0b9f7faa241a658ec2e191">MORPH_CROSS</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( erosion_elem == 2) { erosion_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada33a3c67a61f349d21c507d05c53a755f">MORPH_ELLIPSE</a>; }</div><div class="line"></div><div class="line">  <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">getStructuringElement</a>( erosion_type,</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>( 2*erosion_size + 1, 2*erosion_size+1 ),</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( erosion_size, erosion_size ) );</div><div class="line"></div><div class="line">  <a class="code" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">erode</a>( src, erosion_dst, element );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>( <span class="stringliteral">&quot;Erosion Demo&quot;</span>, erosion_dst );</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">void</span> Dilation( <span class="keywordtype">int</span>, <span class="keywordtype">void</span>* )</div><div class="line">{</div><div class="line">  <span class="keywordtype">int</span> dilation_type = 0;</div><div class="line">  <span class="keywordflow">if</span>( dilation_elem == 0 ){ dilation_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada260c4cbde19a749726763c01a074c60f">MORPH_RECT</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( dilation_elem == 1 ){ dilation_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada318435753d0b9f7faa241a658ec2e191">MORPH_CROSS</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( dilation_elem == 2) { dilation_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada33a3c67a61f349d21c507d05c53a755f">MORPH_ELLIPSE</a>; }</div><div class="line"></div><div class="line">  <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">getStructuringElement</a>( dilation_type,</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>( 2*dilation_size + 1, 2*dilation_size+1 ),</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( dilation_size, dilation_size ) );</div><div class="line"></div><div class="line">  <a class="code" href="../../d4/d86/group__imgproc__filter.html#ga4ff0f3318642c4f469d0e11f242f3b6c">dilate</a>( src, dilation_dst, element );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>( <span class="stringliteral">&quot;Dilation Demo&quot;</span>, dilation_dst );</div><div class="line">}</div></div><!-- fragment -->  </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'><p> This tutorial's code is shown below. You can also download it <a href="https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java">here</a> </p><div class="fragment"><div class="line"><span class="keyword">import</span> java.awt.BorderLayout;</div><div class="line"><span class="keyword">import</span> java.awt.Container;</div><div class="line"><span class="keyword">import</span> java.awt.Image;</div><div class="line"><span class="keyword">import</span> java.awt.event.ActionEvent;</div><div class="line"><span class="keyword">import</span> java.awt.event.ActionListener;</div><div class="line"></div><div class="line"><span class="keyword">import</span> javax.swing.BoxLayout;</div><div class="line"><span class="keyword">import</span> javax.swing.ImageIcon;</div><div class="line"><span class="keyword">import</span> javax.swing.JComboBox;</div><div class="line"><span class="keyword">import</span> javax.swing.JFrame;</div><div class="line"><span class="keyword">import</span> javax.swing.JLabel;</div><div class="line"><span class="keyword">import</span> javax.swing.JPanel;</div><div class="line"><span class="keyword">import</span> javax.swing.JSlider;</div><div class="line"><span class="keyword">import</span> javax.swing.event.ChangeEvent;</div><div class="line"><span class="keyword">import</span> javax.swing.event.ChangeListener;</div><div class="line"></div><div class="line"><span class="keyword">import</span> org.opencv.core.Core;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Mat;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Point;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Size;</div><div class="line"><span class="keyword">import</span> org.opencv.highgui.HighGui;</div><div class="line"><span class="keyword">import</span> org.opencv.imgcodecs.Imgcodecs;</div><div class="line"><span class="keyword">import</span> org.opencv.imgproc.Imgproc;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="keyword">class </span>MorphologyDemo1 {</div><div class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] ELEMENT_TYPE = { <span class="stringliteral">&quot;Rectangle&quot;</span>, <span class="stringliteral">&quot;Cross&quot;</span>, <span class="stringliteral">&quot;Ellipse&quot;</span> };</div><div class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] MORPH_OP = { <span class="stringliteral">&quot;Erosion&quot;</span>, <span class="stringliteral">&quot;Dilatation&quot;</span> };</div><div class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keywordtype">int</span> MAX_KERNEL_SIZE = 21;</div><div class="line">    <span class="keyword">private</span> Mat matImgSrc;</div><div class="line">    <span class="keyword">private</span> Mat matImgDst = <span class="keyword">new</span> Mat();</div><div class="line">    <span class="keyword">private</span> <span class="keywordtype">int</span> elementType = Imgproc.CV_SHAPE_RECT;</div><div class="line">    <span class="keyword">private</span> <span class="keywordtype">int</span> kernelSize = 0;</div><div class="line">    <span class="keyword">private</span> <span class="keywordtype">boolean</span> doErosion = <span class="keyword">true</span>;</div><div class="line">    <span class="keyword">private</span> JFrame frame;</div><div class="line">    <span class="keyword">private</span> JLabel imgLabel;</div><div class="line"></div><div class="line">    <span class="keyword">public</span> MorphologyDemo1(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> imagePath = args.length &gt; 0 ? args[0] : <span class="stringliteral">&quot;../data/LinuxLogo.jpg&quot;</span>;</div><div class="line">        matImgSrc = Imgcodecs.imread(imagePath);</div><div class="line">        <span class="keywordflow">if</span> (matImgSrc.empty()) {</div><div class="line">            System.out.println(<span class="stringliteral">&quot;Empty image: &quot;</span> + imagePath);</div><div class="line">            System.exit(0);</div><div class="line">        }</div><div class="line"></div><div class="line">        <span class="comment">// Create and set up the window.</span></div><div class="line">        frame = <span class="keyword">new</span> JFrame(<span class="stringliteral">&quot;Erosion and dilatation demo&quot;</span>);</div><div class="line">        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);</div><div class="line">        <span class="comment">// Set up the content pane.</span></div><div class="line">        Image img = HighGui.toBufferedImage(matImgSrc);</div><div class="line">        addComponentsToPane(frame.getContentPane(), img);</div><div class="line">        <span class="comment">// Use the content pane&#39;s default BorderLayout. No need for</span></div><div class="line">        <span class="comment">// setLayout(new BorderLayout());</span></div><div class="line">        <span class="comment">// Display the window.</span></div><div class="line">        frame.pack();</div><div class="line">        frame.setVisible(<span class="keyword">true</span>);</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keyword">private</span> <span class="keywordtype">void</span> addComponentsToPane(Container pane, Image img) {</div><div class="line">        <span class="keywordflow">if</span> (!(pane.getLayout() instanceof BorderLayout)) {</div><div class="line">            pane.add(<span class="keyword">new</span> JLabel(<span class="stringliteral">&quot;Container doesn&#39;t use BorderLayout!&quot;</span>));</div><div class="line">            <span class="keywordflow">return</span>;</div><div class="line">        }</div><div class="line"></div><div class="line">        JPanel sliderPanel = <span class="keyword">new</span> JPanel();</div><div class="line">        sliderPanel.setLayout(<span class="keyword">new</span> BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));</div><div class="line"></div><div class="line">        JComboBox&lt;String&gt; elementTypeBox = <span class="keyword">new</span> JComboBox&lt;&gt;(ELEMENT_TYPE);</div><div class="line">        elementTypeBox.addActionListener(<span class="keyword">new</span> ActionListener() {</div><div class="line">            @Override</div><div class="line">            <span class="keyword">public</span> <span class="keywordtype">void</span> actionPerformed(ActionEvent e) {</div><div class="line">                @SuppressWarnings(<span class="stringliteral">&quot;unchecked&quot;</span>)</div><div class="line">                JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt; cb = (JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;)e.getSource();</div><div class="line">                if (cb.getSelectedIndex() == 0) {</div><div class="line">                    elementType = Imgproc.CV_SHAPE_RECT;</div><div class="line">                } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (cb.getSelectedIndex() == 1) {</div><div class="line">                    elementType = Imgproc.CV_SHAPE_CROSS;</div><div class="line">                } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (cb.getSelectedIndex() == 2) {</div><div class="line">                    elementType = Imgproc.CV_SHAPE_ELLIPSE;</div><div class="line">                }</div><div class="line">                update();</div><div class="line">            }</div><div class="line">        });</div><div class="line">        sliderPanel.add(elementTypeBox);</div><div class="line"></div><div class="line">        sliderPanel.add(<span class="keyword">new</span> JLabel(<span class="stringliteral">&quot;Kernel size: 2n + 1&quot;</span>));</div><div class="line">        JSlider slider = <span class="keyword">new</span> JSlider(0, MAX_KERNEL_SIZE, 0);</div><div class="line">        slider.setMajorTickSpacing(5);</div><div class="line">        slider.setMinorTickSpacing(5);</div><div class="line">        slider.setPaintTicks(<span class="keyword">true</span>);</div><div class="line">        slider.setPaintLabels(<span class="keyword">true</span>);</div><div class="line">        slider.addChangeListener(<span class="keyword">new</span> ChangeListener() {</div><div class="line">            @Override</div><div class="line">            <span class="keyword">public</span> <span class="keywordtype">void</span> stateChanged(ChangeEvent e) {</div><div class="line">                JSlider source = (JSlider) e.getSource();</div><div class="line">                kernelSize = source.getValue();</div><div class="line">                update();</div><div class="line">            }</div><div class="line">        });</div><div class="line">        sliderPanel.add(slider);</div><div class="line"></div><div class="line">        JComboBox&lt;String&gt; morphOpBox = <span class="keyword">new</span> JComboBox&lt;&gt;(MORPH_OP);</div><div class="line">        morphOpBox.addActionListener(<span class="keyword">new</span> ActionListener() {</div><div class="line">            @Override</div><div class="line">            <span class="keyword">public</span> <span class="keywordtype">void</span> actionPerformed(ActionEvent e) {</div><div class="line">                @SuppressWarnings(<span class="stringliteral">&quot;unchecked&quot;</span>)</div><div class="line">                JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt; cb = (JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;)e.getSource();</div><div class="line">                doErosion = cb.getSelectedIndex() == 0;</div><div class="line">                update();</div><div class="line">            }</div><div class="line">        });</div><div class="line">        sliderPanel.<a class="code" href="../../d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6">add</a>(morphOpBox);</div><div class="line"></div><div class="line">        pane.<a class="code" href="../../d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6">add</a>(sliderPanel, BorderLayout.PAGE_START);</div><div class="line">        imgLabel = new JLabel(new ImageIcon(img));</div><div class="line">        pane.<a class="code" href="../../d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6">add</a>(imgLabel, BorderLayout.CENTER);</div><div class="line">    }</div><div class="line"></div><div class="line">    private <span class="keywordtype">void</span> update() {</div><div class="line">        Mat element = Imgproc.getStructuringElement(elementType, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>(2 * kernelSize + 1, 2 * kernelSize + 1),</div><div class="line">                <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(kernelSize, kernelSize));</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span> (doErosion) {</div><div class="line">            Imgproc.erode(matImgSrc, matImgDst, element);</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            Imgproc.dilate(matImgSrc, matImgDst, element);</div><div class="line">        }</div><div class="line">        Image img = HighGui.toBufferedImage(matImgDst);</div><div class="line">        imgLabel.setIcon(<span class="keyword">new</span> ImageIcon(img));</div><div class="line">        frame.repaint();</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keywordtype">void</span> main(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <span class="comment">// Load the native OpenCV library</span></div><div class="line">        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);</div><div class="line"></div><div class="line">        <span class="comment">// Schedule a job for the event dispatch thread:</span></div><div class="line">        <span class="comment">// creating and showing this application&#39;s GUI.</span></div><div class="line">        javax.swing.SwingUtilities.invokeLater(<span class="keyword">new</span> Runnable() {</div><div class="line">            @Override</div><div class="line">            <span class="keyword">public</span> <span class="keywordtype">void</span> run() {</div><div class="line">                <span class="keyword">new</span> MorphologyDemo1(args);</div><div class="line">            }</div><div class="line">        });</div><div class="line">    }</div><div class="line">}</div></div><!-- fragment -->  </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'><p> This tutorial's code is shown below. You can also download it <a href="https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py">here</a> </p><div class="fragment"><div class="line"><span class="keyword">from</span> __future__ <span class="keyword">import</span> print_function</div><div class="line"><span class="keyword">import</span> cv2 <span class="keyword">as</span> cv</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> argparse</div><div class="line"></div><div class="line">src = <span class="keywordtype">None</span></div><div class="line">erosion_size = 0</div><div class="line">max_elem = 2</div><div class="line">max_kernel_size = 21</div><div class="line">title_trackbar_element_shape = <span class="stringliteral">&#39;Element:\n 0: Rect \n 1: Cross \n 2: Ellipse&#39;</span></div><div class="line">title_trackbar_kernel_size = <span class="stringliteral">&#39;Kernel size:\n 2n +1&#39;</span></div><div class="line">title_erosion_window = <span class="stringliteral">&#39;Erosion Demo&#39;</span></div><div class="line">title_dilation_window = <span class="stringliteral">&#39;Dilation Demo&#39;</span></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">def </span>main(image):</div><div class="line">    <span class="keyword">global</span> src</div><div class="line">    src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(image))</div><div class="line">    <span class="keywordflow">if</span> src <span class="keywordflow">is</span> <span class="keywordtype">None</span>:</div><div class="line">        <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Could not open or find the image: &#39;</span>, image)</div><div class="line">        exit(0)</div><div class="line"></div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">cv.namedWindow</a>(title_erosion_window)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_element_shape, title_erosion_window, 0, max_elem, erosion)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_kernel_size, title_erosion_window, 0, max_kernel_size, erosion)</div><div class="line"></div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">cv.namedWindow</a>(title_dilation_window)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_element_shape, title_dilation_window, 0, max_elem, dilatation)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_kernel_size, title_dilation_window, 0, max_kernel_size, dilatation)</div><div class="line"></div><div class="line">    erosion(0)</div><div class="line">    dilatation(0)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">cv.waitKey</a>()</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment"># optional mapping of values with morphological shapes</span></div><div class="line"><span class="keyword">def </span>morph_shape(val):</div><div class="line">    <span class="keywordflow">if</span> val == 0:</div><div class="line">        <span class="keywordflow">return</span> cv.MORPH_RECT</div><div class="line">    <span class="keywordflow">elif</span> val == 1:</div><div class="line">        <span class="keywordflow">return</span> cv.MORPH_CROSS</div><div class="line">    <span class="keywordflow">elif</span> val == 2:</div><div class="line">        <span class="keywordflow">return</span> cv.MORPH_ELLIPSE</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">def </span>erosion(val):</div><div class="line">    erosion_size = <a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_kernel_size, title_erosion_window)</div><div class="line">    erosion_shape = morph_shape(<a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_element_shape, title_erosion_window))</div><div class="line"></div><div class="line">    </div><div class="line">    element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">cv.getStructuringElement</a>(erosion_shape, (2 * erosion_size + 1, 2 * erosion_size + 1),</div><div class="line">                                       (erosion_size, erosion_size))</div><div class="line">    </div><div class="line">    erosion_dst = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">cv.erode</a>(src, element)</div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(title_erosion_window, erosion_dst)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">def </span>dilatation(val):</div><div class="line">    dilatation_size = <a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_kernel_size, title_dilation_window)</div><div class="line">    dilation_shape = morph_shape(<a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_element_shape, title_dilation_window))</div><div class="line"></div><div class="line">    element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">cv.getStructuringElement</a>(dilation_shape, (2 * dilatation_size + 1, 2 * dilatation_size + 1),</div><div class="line">                                       (dilatation_size, dilatation_size))</div><div class="line">    dilatation_dst = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ga4ff0f3318642c4f469d0e11f242f3b6c">cv.dilate</a>(src, element)</div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(title_dilation_window, dilatation_dst)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordflow">if</span> __name__ == <span class="stringliteral">&quot;__main__&quot;</span>:</div><div class="line">    parser = argparse.ArgumentParser(description=<span class="stringliteral">&#39;Code for Eroding and Dilating tutorial.&#39;</span>)</div><div class="line">    parser.add_argument(<span class="stringliteral">&#39;--input&#39;</span>, help=<span class="stringliteral">&#39;Path to input image.&#39;</span>, default=<span class="stringliteral">&#39;LinuxLogo.jpg&#39;</span>)</div><div class="line">    args = parser.parse_args()</div><div class="line"></div><div class="line">    main(args.input)</div></div><!-- fragment -->  </div> <h2>Explanation </h2>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'><p> Most of the material shown here is trivial (if you have any doubt, please refer to the tutorials in previous sections). Let's check the general structure of the C++ program:</p>
<div class="fragment"><div class="line"></div><div class="line"><span class="keywordtype">int</span> main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>** argv )</div><div class="line">{</div><div class="line">  CommandLineParser parser( argc, argv, <span class="stringliteral">&quot;{@input | LinuxLogo.jpg | input image}&quot;</span> );</div><div class="line">  src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;( <span class="stringliteral">&quot;@input&quot;</span> ) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80af660544735200cbe942eea09232eb822">IMREAD_COLOR</a> );</div><div class="line">  <span class="keywordflow">if</span>( src.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#abbec3525a852e77998aba034813fded4">empty</a>() )</div><div class="line">  {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Could not open or find the image!\n&quot;</span> &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Usage: &quot;</span> &lt;&lt; argv[0] &lt;&lt; <span class="stringliteral">&quot; &lt;Input image&gt;&quot;</span> &lt;&lt; endl;</div><div class="line">    <span class="keywordflow">return</span> -1;</div><div class="line">  }</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">namedWindow</a>( <span class="stringliteral">&quot;Erosion Demo&quot;</span>, <a class="code" href="../../d0/d90/group__highgui__window__flags.html#ggabf7d2c5625bc59ac130287f925557ac3acf621ace7a54954cbac01df27e47228f">WINDOW_AUTOSIZE</a> );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">namedWindow</a>( <span class="stringliteral">&quot;Dilation Demo&quot;</span>, <a class="code" href="../../d0/d90/group__highgui__window__flags.html#ggabf7d2c5625bc59ac130287f925557ac3acf621ace7a54954cbac01df27e47228f">WINDOW_AUTOSIZE</a> );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga8d86b207f7211250dbe6e28f76307ffb">moveWindow</a>( <span class="stringliteral">&quot;Dilation Demo&quot;</span>, src.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa3e5a47585c9ef6a0842556739155e3e">cols</a>, 0 );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Element:\n 0: Rect \n 1: Cross \n 2: Ellipse&quot;</span>, <span class="stringliteral">&quot;Erosion Demo&quot;</span>,</div><div class="line">          &amp;erosion_elem, max_elem,</div><div class="line">          Erosion );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Kernel size:\n 2n +1&quot;</span>, <span class="stringliteral">&quot;Erosion Demo&quot;</span>,</div><div class="line">          &amp;erosion_size, max_kernel_size,</div><div class="line">          Erosion );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Element:\n 0: Rect \n 1: Cross \n 2: Ellipse&quot;</span>, <span class="stringliteral">&quot;Dilation Demo&quot;</span>,</div><div class="line">          &amp;dilation_elem, max_elem,</div><div class="line">          Dilation );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">createTrackbar</a>( <span class="stringliteral">&quot;Kernel size:\n 2n +1&quot;</span>, <span class="stringliteral">&quot;Dilation Demo&quot;</span>,</div><div class="line">          &amp;dilation_size, max_kernel_size,</div><div class="line">          Dilation );</div><div class="line"></div><div class="line">  Erosion( 0, 0 );</div><div class="line">  Dilation( 0, 0 );</div><div class="line"></div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">waitKey</a>(0);</div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><ol type="1">
<li>Load an image (can be BGR or grayscale)</li>
<li>Create two windows (one for dilation output, the other for erosion)</li>
<li>Create a set of two Trackbars for each operation:<ul>
<li>The first trackbar "Element" returns either <b>erosion_elem</b> or <b>dilation_elem</b></li>
<li>The second trackbar "Kernel size" return <b>erosion_size</b> or <b>dilation_size</b> for the corresponding operation.</li>
</ul>
</li>
<li>Call once erosion and dilation to show the initial image.</li>
</ol>
<p>Every time we move any slider, the user's function <b>Erosion</b> or <b>Dilation</b> will be called and it will update the output image based on the current trackbar values.</p>
<p>Let's analyze these two functions:</p>
<h4>The erosion function</h4>
<div class="fragment"><div class="line"></div><div class="line"><span class="keywordtype">void</span> Erosion( <span class="keywordtype">int</span>, <span class="keywordtype">void</span>* )</div><div class="line">{</div><div class="line">  <span class="keywordtype">int</span> erosion_type = 0;</div><div class="line">  <span class="keywordflow">if</span>( erosion_elem == 0 ){ erosion_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada260c4cbde19a749726763c01a074c60f">MORPH_RECT</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( erosion_elem == 1 ){ erosion_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada318435753d0b9f7faa241a658ec2e191">MORPH_CROSS</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( erosion_elem == 2) { erosion_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada33a3c67a61f349d21c507d05c53a755f">MORPH_ELLIPSE</a>; }</div><div class="line"></div><div class="line">  Mat element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">getStructuringElement</a>( erosion_type,</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>( 2*erosion_size + 1, 2*erosion_size+1 ),</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( erosion_size, erosion_size ) );</div><div class="line"></div><div class="line">  <a class="code" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">erode</a>( src, erosion_dst, element );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>( <span class="stringliteral">&quot;Erosion Demo&quot;</span>, erosion_dst );</div><div class="line">}</div></div><!-- fragment --><p> The function that performs the <em>erosion</em> operation is <a class="el" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">cv::erode</a> . As we can see, it receives three arguments:</p><ul>
<li><em>src</em>: The source image</li>
<li><em>erosion_dst</em>: The output image</li>
<li><p class="startli"><em>element</em>: This is the kernel we will use to perform the operation. If we do not specify, the default is a simple <code>3x3</code> matrix. Otherwise, we can specify its shape. For this, we need to use the function <a class="el" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc" title="Returns a structuring element of the specified size and shape for morphological operations. ">cv::getStructuringElement</a> : </p><div class="fragment"><div class="line">  Mat element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">getStructuringElement</a>( erosion_type,</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>( 2*erosion_size + 1, 2*erosion_size+1 ),</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( erosion_size, erosion_size ) );</div></div><!-- fragment --><p> We can choose any of three shapes for our kernel:</p><ul>
<li>Rectangular box: MORPH_RECT</li>
<li>Cross: MORPH_CROSS</li>
<li>Ellipse: MORPH_ELLIPSE</li>
</ul>
<p class="startli">Then, we just have to specify the size of our kernel and the <em>anchor point</em>. If not specified, it is assumed to be in the center.</p>
</li>
</ul>
<p>That is all. We are ready to perform the erosion of our image.</p>
<h4>The dilation function</h4>
<p>The code is below. As you can see, it is completely similar to the snippet of code for <b>erosion</b>. Here we also have the option of defining our kernel, its anchor point and the size of the operator to be used. </p><div class="fragment"><div class="line"></div><div class="line"><span class="keywordtype">void</span> Dilation( <span class="keywordtype">int</span>, <span class="keywordtype">void</span>* )</div><div class="line">{</div><div class="line">  <span class="keywordtype">int</span> dilation_type = 0;</div><div class="line">  <span class="keywordflow">if</span>( dilation_elem == 0 ){ dilation_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada260c4cbde19a749726763c01a074c60f">MORPH_RECT</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( dilation_elem == 1 ){ dilation_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada318435753d0b9f7faa241a658ec2e191">MORPH_CROSS</a>; }</div><div class="line">  <span class="keywordflow">else</span> <span class="keywordflow">if</span>( dilation_elem == 2) { dilation_type = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ggac2db39b56866583a95a5680313c314ada33a3c67a61f349d21c507d05c53a755f">MORPH_ELLIPSE</a>; }</div><div class="line"></div><div class="line">  Mat element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">getStructuringElement</a>( dilation_type,</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>( 2*dilation_size + 1, 2*dilation_size+1 ),</div><div class="line">                       <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( dilation_size, dilation_size ) );</div><div class="line"></div><div class="line">  <a class="code" href="../../d4/d86/group__imgproc__filter.html#ga4ff0f3318642c4f469d0e11f242f3b6c">dilate</a>( src, dilation_dst, element );</div><div class="line">  <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>( <span class="stringliteral">&quot;Dilation Demo&quot;</span>, dilation_dst );</div><div class="line">}</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'><p> Most of the material shown here is trivial (if you have any doubt, please refer to the tutorials in previous sections). Let's check however the general structure of the java class. There are 4 main parts in the java class:</p>
<ul>
<li>the class constructor which setups the window that will be filled with window components</li>
<li>the <code>addComponentsToPane</code> method, which fills out the window</li>
<li>the <code>update</code> method, which determines what happens when the user changes any value</li>
<li>the <code>main</code> method, which is the entry point of the program</li>
</ul>
<p>In this tutorial we will focus on the <code>addComponentsToPane</code> and <code>update</code> methods. However, for completion the steps followed in the constructor are:</p>
<ol type="1">
<li>Load an image (can be BGR or grayscale)</li>
<li>Create a window</li>
<li>Add various control components with <code>addComponentsToPane</code></li>
<li>show the window</li>
</ol>
<p>The components were added by the following method:</p>
<div class="fragment"><div class="line">    <span class="keyword">private</span> <span class="keywordtype">void</span> addComponentsToPane(Container pane, Image img) {</div><div class="line">        <span class="keywordflow">if</span> (!(pane.getLayout() instanceof BorderLayout)) {</div><div class="line">            pane.add(<span class="keyword">new</span> JLabel(<span class="stringliteral">&quot;Container doesn&#39;t use BorderLayout!&quot;</span>));</div><div class="line">            <span class="keywordflow">return</span>;</div><div class="line">        }</div><div class="line"></div><div class="line">        JPanel sliderPanel = <span class="keyword">new</span> JPanel();</div><div class="line">        sliderPanel.setLayout(<span class="keyword">new</span> BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));</div><div class="line"></div><div class="line">        JComboBox&lt;String&gt; elementTypeBox = <span class="keyword">new</span> JComboBox&lt;&gt;(ELEMENT_TYPE);</div><div class="line">        elementTypeBox.addActionListener(<span class="keyword">new</span> ActionListener() {</div><div class="line">            @Override</div><div class="line">            <span class="keyword">public</span> <span class="keywordtype">void</span> actionPerformed(ActionEvent e) {</div><div class="line">                @SuppressWarnings(<span class="stringliteral">&quot;unchecked&quot;</span>)</div><div class="line">                JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt; cb = (JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;)e.getSource();</div><div class="line">                if (cb.getSelectedIndex() == 0) {</div><div class="line">                    elementType = Imgproc.CV_SHAPE_RECT;</div><div class="line">                } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (cb.getSelectedIndex() == 1) {</div><div class="line">                    elementType = Imgproc.CV_SHAPE_CROSS;</div><div class="line">                } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (cb.getSelectedIndex() == 2) {</div><div class="line">                    elementType = Imgproc.CV_SHAPE_ELLIPSE;</div><div class="line">                }</div><div class="line">                update();</div><div class="line">            }</div><div class="line">        });</div><div class="line">        sliderPanel.add(elementTypeBox);</div><div class="line"></div><div class="line">        sliderPanel.add(<span class="keyword">new</span> JLabel(<span class="stringliteral">&quot;Kernel size: 2n + 1&quot;</span>));</div><div class="line">        JSlider slider = <span class="keyword">new</span> JSlider(0, MAX_KERNEL_SIZE, 0);</div><div class="line">        slider.setMajorTickSpacing(5);</div><div class="line">        slider.setMinorTickSpacing(5);</div><div class="line">        slider.setPaintTicks(<span class="keyword">true</span>);</div><div class="line">        slider.setPaintLabels(<span class="keyword">true</span>);</div><div class="line">        slider.addChangeListener(<span class="keyword">new</span> ChangeListener() {</div><div class="line">            @Override</div><div class="line">            <span class="keyword">public</span> <span class="keywordtype">void</span> stateChanged(ChangeEvent e) {</div><div class="line">                JSlider source = (JSlider) e.getSource();</div><div class="line">                kernelSize = source.getValue();</div><div class="line">                update();</div><div class="line">            }</div><div class="line">        });</div><div class="line">        sliderPanel.add(slider);</div><div class="line"></div><div class="line">        JComboBox&lt;String&gt; morphOpBox = <span class="keyword">new</span> JComboBox&lt;&gt;(MORPH_OP);</div><div class="line">        morphOpBox.addActionListener(<span class="keyword">new</span> ActionListener() {</div><div class="line">            @Override</div><div class="line">            <span class="keyword">public</span> <span class="keywordtype">void</span> actionPerformed(ActionEvent e) {</div><div class="line">                @SuppressWarnings(<span class="stringliteral">&quot;unchecked&quot;</span>)</div><div class="line">                JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt; cb = (JComboBox&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;)e.getSource();</div><div class="line">                doErosion = cb.getSelectedIndex() == 0;</div><div class="line">                update();</div><div class="line">            }</div><div class="line">        });</div><div class="line">        sliderPanel.<a class="code" href="../../d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6">add</a>(morphOpBox);</div><div class="line"></div><div class="line">        pane.<a class="code" href="../../d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6">add</a>(sliderPanel, BorderLayout.PAGE_START);</div><div class="line">        imgLabel = new JLabel(new ImageIcon(img));</div><div class="line">        pane.<a class="code" href="../../d2/de8/group__core__array.html#ga10ac1bfb180e2cfda1701d06c24fdbd6">add</a>(imgLabel, BorderLayout.CENTER);</div><div class="line">    }</div></div><!-- fragment --><p> In short we</p>
<ol type="1">
<li>create a panel for the sliders</li>
<li>create a combo box for the element types</li>
<li>create a slider for the kernel size</li>
<li>create a combo box for the morphology function to use (erosion or dilation)</li>
</ol>
<p>The action and state changed listeners added call at the end the <code>update</code> method which updates the image based on the current slider values. So every time we move any slider, the <code>update</code> method is triggered.</p>
<h4>Updating the image</h4>
<p>To update the image we used the following implementation:</p>
<div class="fragment"><div class="line">    <span class="keyword">private</span> <span class="keywordtype">void</span> update() {</div><div class="line">        Mat element = Imgproc.getStructuringElement(elementType, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>(2 * kernelSize + 1, 2 * kernelSize + 1),</div><div class="line">                <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(kernelSize, kernelSize));</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span> (doErosion) {</div><div class="line">            Imgproc.erode(matImgSrc, matImgDst, element);</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            Imgproc.dilate(matImgSrc, matImgDst, element);</div><div class="line">        }</div><div class="line">        Image img = HighGui.toBufferedImage(matImgDst);</div><div class="line">        imgLabel.setIcon(<span class="keyword">new</span> ImageIcon(img));</div><div class="line">        frame.repaint();</div><div class="line">    }</div></div><!-- fragment --><p> In other words we</p>
<ol type="1">
<li>get the structuring element the user chose</li>
<li>execute the <b>erosion</b> or <b>dilation</b> function based on <code>doErosion</code></li>
<li>reload the image with the morphology applied</li>
<li>repaint the frame</li>
</ol>
<p>Let's analyze the <code>erode</code> and <code>dilate</code> methods:</p>
<h4>The erosion method</h4>
<div class="fragment"><div class="line">            Imgproc.erode(matImgSrc, matImgDst, element);</div></div><!-- fragment --><p> The function that performs the <em>erosion</em> operation is <a class="el" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">cv::erode</a> . As we can see, it receives three arguments:</p><ul>
<li><em>src</em>: The source image</li>
<li><em>erosion_dst</em>: The output image</li>
<li><p class="startli"><em>element</em>: This is the kernel we will use to perform the operation. For specifying the shape, we need to use the function <a class="el" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc" title="Returns a structuring element of the specified size and shape for morphological operations. ">cv::getStructuringElement</a> : </p><div class="fragment"><div class="line">        Mat element = Imgproc.getStructuringElement(elementType, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>(2 * kernelSize + 1, 2 * kernelSize + 1),</div><div class="line">                <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(kernelSize, kernelSize));</div></div><!-- fragment --><p> We can choose any of three shapes for our kernel:</p><ul>
<li>Rectangular box: CV_SHAPE_RECT</li>
<li>Cross: CV_SHAPE_CROSS</li>
<li>Ellipse: CV_SHAPE_ELLIPSE</li>
</ul>
<p class="startli">Together with the shape we specify the size of our kernel and the <em>anchor point</em>. If the anchor point is not specified, it is assumed to be in the center.</p>
</li>
</ul>
<p>That is all. We are ready to perform the erosion of our image.</p>
<h4>The dilation function</h4>
<p>The code is below. As you can see, it is completely similar to the snippet of code for <b>erosion</b>. Here we also have the option of defining our kernel, its anchor point and the size of the operator to be used. </p><div class="fragment"><div class="line">            Imgproc.dilate(matImgSrc, matImgDst, element);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'><p> Most of the material shown here is trivial (if you have any doubt, please refer to the tutorials in previous sections). Let's check the general structure of the python script:</p>
<div class="fragment"><div class="line"><span class="keyword">def </span>main(image):</div><div class="line">    <span class="keyword">global</span> src</div><div class="line">    src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(image))</div><div class="line">    <span class="keywordflow">if</span> src <span class="keywordflow">is</span> <span class="keywordtype">None</span>:</div><div class="line">        <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Could not open or find the image: &#39;</span>, image)</div><div class="line">        exit(0)</div><div class="line"></div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">cv.namedWindow</a>(title_erosion_window)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_element_shape, title_erosion_window, 0, max_elem, erosion)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_kernel_size, title_erosion_window, 0, max_kernel_size, erosion)</div><div class="line"></div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5afdf8410934fd099df85c75b2e0888b">cv.namedWindow</a>(title_dilation_window)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_element_shape, title_dilation_window, 0, max_elem, dilatation)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#gaf78d2155d30b728fc413803745b67a9b">cv.createTrackbar</a>(title_trackbar_kernel_size, title_dilation_window, 0, max_kernel_size, dilatation)</div><div class="line"></div><div class="line">    erosion(0)</div><div class="line">    dilatation(0)</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">cv.waitKey</a>()</div></div><!-- fragment --><ol type="1">
<li>Load an image (can be BGR or grayscale)</li>
<li>Create two windows (one for erosion output, the other for dilation) with a set of trackbars each<ul>
<li>The first trackbar "Element" returns the value for the morphological type that will be mapped (1 = rectangle, 2 = cross, 3 = ellipse)</li>
<li>The second trackbar "Kernel size" returns the size of the element for the corresponding operation</li>
</ul>
</li>
<li>Call once erosion and dilation to show the initial image</li>
</ol>
<p>Every time we move any slider, the user's function <b>erosion</b> or <b>dilation</b> will be called and it will update the output image based on the current trackbar values.</p>
<p>Let's analyze these two functions:</p>
<h4>The erosion function</h4>
<div class="fragment"><div class="line"><span class="keyword">def </span>erosion(val):</div><div class="line">    erosion_size = <a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_kernel_size, title_erosion_window)</div><div class="line">    erosion_shape = morph_shape(<a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_element_shape, title_erosion_window))</div><div class="line"></div><div class="line">    </div><div class="line">    element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">cv.getStructuringElement</a>(erosion_shape, (2 * erosion_size + 1, 2 * erosion_size + 1),</div><div class="line">                                       (erosion_size, erosion_size))</div><div class="line">    </div><div class="line">    erosion_dst = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">cv.erode</a>(src, element)</div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(title_erosion_window, erosion_dst)</div></div><!-- fragment --><p> The function that performs the <em>erosion</em> operation is <a class="el" href="../../d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb">cv::erode</a> . As we can see, it receives two arguments and returns the processed image:</p><ul>
<li><em>src</em>: The source image</li>
<li><em>element</em>: The kernel we will use to perform the operation. We can specify its shape by using the function <a class="el" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc" title="Returns a structuring element of the specified size and shape for morphological operations. ">cv::getStructuringElement</a> : <div class="fragment"><div class="line">    element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">cv.getStructuringElement</a>(erosion_shape, (2 * erosion_size + 1, 2 * erosion_size + 1),</div><div class="line">                                       (erosion_size, erosion_size))</div></div><!-- fragment --> We can choose any of three shapes for our kernel:<ul>
<li>Rectangular box: MORPH_RECT</li>
<li>Cross: MORPH_CROSS</li>
<li>Ellipse: MORPH_ELLIPSE</li>
</ul>
</li>
</ul>
<p>Then, we just have to specify the size of our kernel and the <em>anchor point</em>. If the anchor point not specified, it is assumed to be in the center.</p>
<p>That is all. We are ready to perform the erosion of our image.</p>
<h4>The dilation function</h4>
<p>The code is below. As you can see, it is completely similar to the snippet of code for <b>erosion</b>. Here we also have the option of defining our kernel, its anchor point and the size of the operator to be used.</p>
<div class="fragment"><div class="line"><span class="keyword">def </span>dilatation(val):</div><div class="line">    dilatation_size = <a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_kernel_size, title_dilation_window)</div><div class="line">    dilation_shape = morph_shape(<a class="code" href="../../d7/dfc/group__highgui.html#ga122632e9e91b9ec06943472c55d9cda8">cv.getTrackbarPos</a>(title_trackbar_element_shape, title_dilation_window))</div><div class="line"></div><div class="line">    element = <a class="code" href="../../d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc">cv.getStructuringElement</a>(dilation_shape, (2 * dilatation_size + 1, 2 * dilatation_size + 1),</div><div class="line">                                       (dilatation_size, dilatation_size))</div><div class="line">    dilatation_dst = <a class="code" href="../../d4/d86/group__imgproc__filter.html#ga4ff0f3318642c4f469d0e11f242f3b6c">cv.dilate</a>(src, element)</div><div class="line">    <a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(title_dilation_window, dilatation_dst)</div></div><!-- fragment --> </div> <dl class="section note"><dt>Note</dt><dd>Additionally, there are further parameters that allow you to perform multiple erosions/dilations (iterations) at once and also set the border type and value. However, We haven't used those in this simple tutorial. You can check out the reference for more details.</dd></dl>
<h2>Results </h2>
<p>Compile the code above and execute it (or run the script if using python) with an image as argument. If you do not provide an image as argument the default sample image (<a href="https://github.com/opencv/opencv/tree/master/samples/data/LinuxLogo.jpg">LinuxLogo.jpg</a>) will be used.</p>
<p>For instance, using this image:</p>
<div class="image">
<img src="../../Morphology_1_Tutorial_Original_Image.jpg" alt="Morphology_1_Tutorial_Original_Image.jpg"/>
</div>
<p>We get the results below. Varying the indices in the Trackbars give different output images, naturally. Try them out! You can even try to add a third Trackbar to control the number of iterations.</p>
<div class="image">
<img src="../../Morphology_1_Result.jpg" alt="Morphology_1_Result.jpg"/>
</div>
<p> (depending on the programming language the output might vary a little or be only 1 window) </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:35 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
